<template>
  <div class="editor-container">
    <h3>公式编辑器</h3>
    <div style="position: relative">
      <el-button v-hasPerm="['sys:user:add']" type="success" @click="clearFormulaEditor()">
        清除公式
      </el-button>
      <textarea
        ref="formulaBox"
        v-model="formula"
        class="formula-box"
        placeholder="请输入计算公式..."
        @input="handleInput"
        @keydown.down.prevent="moveSelection(1)"
        @keydown.up.prevent="moveSelection(-1)"
        @keydown.enter.prevent="selectSuggestion"
      ></textarea>
      <div v-if="filteredSuggestions.length" class="autocomplete" :style="dropdownStyle">
        <div
          v-for="(suggestion, index) in filteredSuggestions"
          :key="suggestion"
          :class="{ selected: index === selectedIndex }"
          @mouseover="setSelectedIndex(index)"
          @click="insertAtCursor(suggestion, suggestionType === 'field')"
        >
          {{ suggestion }}
        </div>
      </div>
    </div>
    <div class="toolbar">
      <div class="section scrollable fixed-height">
        <h4>字段列表</h4>
        <div
          v-for="field in fields"
          :key="field"
          class="toolbar-item"
          @click="insertAtCursor(field, true)"
          @mouseover="highlightItem"
          @mouseleave="removeHighlight"
        >
          {{ field }}
        </div>
      </div>
      <div class="section scrollable operators fixed-height">
        <h4>运算符</h4>
        <div
          v-for="operator in operators"
          :key="operator"
          class="toolbar-item operator-item"
          @click="insertAtCursor(operator)"
          @mouseover="highlightItem"
          @mouseleave="removeHighlight"
        >
          {{ operator }}
        </div>
      </div>
      <div class="section scrollable fixed-height">
        <h4>函数</h4>
        <div
          v-for="func in functions"
          :key="func"
          class="toolbar-item"
          @click="insertAtCursor(func, false)"
          @mouseover="highlightItem"
          @mouseleave="removeHighlight"
        >
          {{ func }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, nextTick } from "vue";

export default {
  setup() {
    const formula = ref("");
    const formulaBox = ref(null);
    const fields = ["司龄", "薪资结算日", "入职日期", "工资", "奖金", "考勤天数"];
    const operators = ["+", "-", "*", "/", "(", ")"];
    const functions = ["SUM()", "AVG()", "MAX()", "MIN()", "ROUND()", "IF()", "LOG()"];
    const filteredSuggestions = ref([]);
    const selectedIndex = ref(-1);
    const dropdownStyle = ref({});
    const suggestionType = ref("");

    const clearFormulaEditor = (event) => {
      nextTick(() => {
        formula.value = "";
      });
    };

    const highlightItem = (event) => {
      event.target.classList.add("highlight");
    };

    const removeHighlight = (event) => {
      event.target.classList.remove("highlight");
    };

    const handleInput = (event) => {
      const textarea = event.target;
      const value = textarea.value;
      const cursorPos = textarea.selectionStart;
      const rect = textarea.getBoundingClientRect();
      const caretPos = textarea.selectionStart;
      const lineHeight = 20;
      const charWidth = 8;
      debugger;

      const row = (caretPos / textarea.cols) | 0;
      const col = caretPos % textarea.cols;

      dropdownStyle.value = {
        position: "absolute",
        left: `${5 + col * charWidth}px`,
        top: `${30 + row * lineHeight + 30}px`,
      };
      if (value[cursorPos - 1] === "{") {
        filteredSuggestions.value = fields;
        suggestionType.value = "field";
      } else if (value.slice(cursorPos - 3, cursorPos) === "fx:") {
        filteredSuggestions.value = functions;
        suggestionType.value = "function";
      } else {
        filteredSuggestions.value = [];
      }
    };

    const insertAtCursor = (text, isField = false) => {
      const textarea = formulaBox.value;
      if (!textarea) return;
      const start = textarea.selectionStart;
      const end = textarea.selectionEnd;
      const before = formula.value.slice(0, start);
      const after = formula.value.slice(end);
      const insertText = wrpperInsertText(text, isField);
      formula.value = before + insertText + after;
      nextTick(() => {
        textarea.selectionStart = textarea.selectionEnd = start + insertText.length;
        textarea.focus();
      });
      filteredSuggestions.value = [];
      suggestionType.value = "";
    };

    const wrpperInsertText = (text, isField) => {
      if (isField) {
        if (suggestionType.value === "field") {
          //通过{提示插入文本,
          return `${text}}`;
        } else {
          return `{${text}}`;
        }
      } else {
        return text;
      }
    };

    const moveSelection = (direction) => {
      selectedIndex.value =
        (selectedIndex.value + direction + filteredSuggestions.value.length) %
        filteredSuggestions.value.length;
    };

    const setSelectedIndex = (index) => {
      selectedIndex.value = index;
    };

    const selectSuggestion = () => {
      if (selectedIndex.value >= 0) {
        insertAtCursor(
          filteredSuggestions.value[selectedIndex.value],
          suggestionType.value === "field"
        );
      }
    };

    return {
      formula,
      formulaBox,
      fields,
      operators,
      functions,
      filteredSuggestions,
      selectedIndex,
      dropdownStyle,
      suggestionType,
      handleInput,
      insertAtCursor,
      moveSelection,
      setSelectedIndex,
      selectSuggestion,
      highlightItem,
      removeHighlight,
      clearFormulaEditor,
      wrpperInsertText,
    };
  },
};
</script>

<style>
.editor-container {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  width: 700px;
  display: flex;
  flex-direction: column;
}
.toolbar {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
}
.section {
  flex: 1;
  padding: 5px;
}
.scrollable {
  overflow-y: auto;
  border: 1px solid #ddd;
  padding: 5px;
  border-radius: 4px;
}
.fixed-height {
  height: 280px;
}

.section h4 {
  margin-bottom: 5px;
  font-size: 14px;
}
.toolbar-item {
  padding: 5px;
  cursor: pointer;
  background: #f9f9f9;
  border-radius: 4px;
  margin: 2px;
}
.toolbar-item:hover,
.toolbar-item.highlight {
  background: #1d63ef;
}
.autocomplete {
  background: white;
  border: 2px solid #ccc;
  max-height: 150px;
  overflow-y: auto;
  position: absolute;
  z-index: 1000;
  width: 200px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.selected {
  background: #f0f0f0;
}

.operators .toolbar-item {
  background: #aeaeac;
  font-weight: bold;
}
.formula-box {
  width: 100%;
  height: 180px;
  padding: 8px;
  margin-bottom: 10px;
  font-size: 16px;
  border: 1px solid #ccc;
  border-radius: 4px;
}
</style>
